package com.itlong.cloud.controller.project;

import com.itlong.cloud.POJO.DTO.operate.*;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.robot.AppRobotAccountInfoGetVO;
import com.itlong.cloud.POJO.VO.app.robot.AppRobotLoginCacheVO;
import com.itlong.cloud.POJO.VO.operate.OperateRobotAccountGetOneVO;
import com.itlong.cloud.POJO.VO.operate.OperateRobotAccountGetPageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.project.operate.IOperateRobotAccountServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppRobotLoginServiceClient;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      运营-机器人账号管理控制器
 * </desc>
 *
 * @createDate 2018/10/11
 */
@RestController
@RequestMapping("/project/robotUser")
@RefreshScope
public class OperateRobotAccountController extends BaseController {

    @Autowired
    private IOperateRobotAccountServiceClient iOperateRobotAccountServiceClient;

    @Autowired
    private IAppRobotLoginServiceClient iAppRobotLoginServiceClient;

    @Autowired
    private RedisService<AppRobotLoginCacheVO> redisService;

    @Value("${" + PlatformConstants.OPERATE_USER_PASSWORD_KEY + "}")
    String userPasswordKey;

    /**
     * <desc>
     *      添加机器人账号
     * </desc>
     *
     * @param operateRobotAccountSaveDTO 添加机器人账号信息数据DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/12
     */
    @ResponseBody
    @PostMapping(path = "save")
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.ROBOT_ACCOUNT_SAVE_LOG_DESC)
    public Object saveRobotAccount(OperateRobotAccountSaveDTO operateRobotAccountSaveDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateRobotAccountSaveDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateRobotAccountSaveDTO.class,request);
            if (operateRobotAccountSaveDTO == null || StringUtils.isBlank(operateRobotAccountSaveDTO.getRobotProjectName()) || StringUtils.isBlank(operateRobotAccountSaveDTO.getAccount())
                    || StringUtils.isBlank(operateRobotAccountSaveDTO.getPassword()) || StringUtils.isBlank(operateRobotAccountSaveDTO.getOperationTimeString()) ||
                    StringUtils.isBlank(operateRobotAccountSaveDTO.getAbateTimeString())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 暂时注释掉，机器人项目开发时间待定，到时解开
//            if (StringUtils.isBlank(operateRobotAccountSaveDTO.getProjectId())) {
//                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
//            }
            OperateRobotAccountGetOneDTO operateRobotAccountGetOneDTO = new OperateRobotAccountGetOneDTO();
            operateRobotAccountGetOneDTO.setAccount(operateRobotAccountSaveDTO.getAccount());
            OperateRobotAccountGetOneVO operateRobotAccountGetOneVO = iOperateRobotAccountServiceClient.getOneRobotAccount(operateRobotAccountGetOneDTO);
            if (operateRobotAccountGetOneVO != null) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_EXIST_ERR.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateRobotAccountSaveDTO.getLoginCount(), 1, 4)) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_LOGIN_COUNT_ERR.getErrorCode());
            }
            if (operateRobotAccountSaveDTO.getUseStatus() != 1 && operateRobotAccountSaveDTO.getUseStatus() != 2) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_STATUS_ERR.getErrorCode());
            }
            operateRobotAccountSaveDTO.setPassword(UserTokenUtil.getPassword(operateRobotAccountSaveDTO.getPassword(),userPasswordKey));
            Date operationTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(operateRobotAccountSaveDTO.getOperationTimeString());
            Date abateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(operateRobotAccountSaveDTO.getAbateTimeString());
            if (!(operationTime.compareTo(abateTime) < 0)) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_TIME_ERR.getErrorCode());
            }
            iOperateRobotAccountServiceClient.saveRobotAccount(operateRobotAccountSaveDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】添加机器人账号信息失败",e);
        }
    }

    /**
     * <desc>
     *      查询单个机器人账号信息
     * </desc>
     *
     * @param operateRobotAccountGetOneDTO 查询单个机器人账号信息数据DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/12
     */
    @ResponseBody
    @PostMapping(path = "getOne")
    public Object getOneRobotAccount(OperateRobotAccountGetOneDTO operateRobotAccountGetOneDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateRobotAccountGetOneDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateRobotAccountGetOneDTO.class,request);
            if (operateRobotAccountGetOneDTO == null || StringUtils.isBlank(operateRobotAccountGetOneDTO.getAppRobotAccountId())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            OperateRobotAccountGetOneVO operateRobotAccountGetOneVO = iOperateRobotAccountServiceClient.getOneRobotAccount(operateRobotAccountGetOneDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),operateRobotAccountGetOneVO);
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】查询单个机器人账号信息失败",e);
        }
    }

    /**
     * <desc>
     *      分页查询机器人账号信息
     * </desc>
     *
     * @param operateRobotAccountGetPageDTO 分页查询机器人账号信息数据DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/12
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "getPage")
    public Object getRobotAccountByPage(OperateRobotAccountGetPageDTO operateRobotAccountGetPageDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateRobotAccountGetPageDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateRobotAccountGetPageDTO.class,request);
            if (operateRobotAccountGetPageDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<OperateRobotAccountGetPageVO> operateRobotAccountGetPageVOS = iOperateRobotAccountServiceClient.getRobotAccountByPage(operateRobotAccountGetPageDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),operateRobotAccountGetPageVOS);
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】分页查询机器人账号信息失败",e);
        }
    }

    /**
     * <desc>
     *      修改机器人账号信息
     * </desc>
     *
     * @param operateRobotAccountUpdateDTO 修改机器人账号信息数据DTO
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/12
     */
    @ResponseBody
    @PostMapping(path = "update")
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.ROBOT_ACCOUNT_UPDATE_LOG_DESC)
    public Object updateRobotAccount(OperateRobotAccountUpdateDTO operateRobotAccountUpdateDTO){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateRobotAccountUpdateDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateRobotAccountUpdateDTO.class,request);
            if (operateRobotAccountUpdateDTO == null || StringUtils.isBlank(operateRobotAccountUpdateDTO.getOperationTimeString())
                    || StringUtils.isBlank(operateRobotAccountUpdateDTO.getAbateTimeString())) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (!NumberHandlerUtil.isInRange(operateRobotAccountUpdateDTO.getLoginCount(), 1, 4)) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_LOGIN_COUNT_ERR.getErrorCode());
            }
            if (operateRobotAccountUpdateDTO.getUseStatus() != 1 && operateRobotAccountUpdateDTO.getUseStatus() != 2) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_STATUS_ERR.getErrorCode());
            }
            // 暂时注释掉，机器人项目开发时间待定，到时解开
//            if (StringUtils.isBlank(operateRobotAccountUpdateDTO.getProjectId())) {
//                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
//            }
            String cacheKey = String.format("%s%s", RedisConstant.ROBOT_USER_REDIS_KEY, operateRobotAccountUpdateDTO.getAppRobotAccountId());
            // 修改时若禁用了账号，则清除缓存
            if (operateRobotAccountUpdateDTO.getUseStatus() == 2) {
                redisService.del(cacheKey);
            }
            AppRobotLoginCacheVO appRobotLoginCacheVO = redisService.getObject(RedisConstant.ROBOT_USER_REDIS_KEY + operateRobotAccountUpdateDTO.getAppRobotAccountId(), AppRobotLoginCacheVO.class);
            if (appRobotLoginCacheVO != null) {
                List<String> robotUniques = appRobotLoginCacheVO.getRobotUniques();
                if (robotUniques != null && operateRobotAccountUpdateDTO.getLoginCount() < robotUniques.size()) {
                    // 同时登录限制数修改之后少于当前已登录数，则清除缓存
                    redisService.del(cacheKey);
                }
            }
            if (StringUtils.isNotBlank(operateRobotAccountUpdateDTO.getPassword())) {
                operateRobotAccountUpdateDTO.setPassword(UserTokenUtil.getPassword(operateRobotAccountUpdateDTO.getPassword(),userPasswordKey));
                redisService.del(cacheKey);
            } else {
                operateRobotAccountUpdateDTO.setPassword(null);
            }
            Date operationTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(operateRobotAccountUpdateDTO.getOperationTimeString());
            Date abateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(operateRobotAccountUpdateDTO.getAbateTimeString());
            Date nowTime = new Date();
            if (!(operationTime.compareTo(abateTime) < 0)) {
                return new MessageVO(OperateErrorCodeEnum.ROBOT_ACCOUNT_TIME_ERR.getErrorCode());
            }
            // 修改了生效时间或过期时间时
            if (abateTime.compareTo(nowTime) <= 0 || operationTime.compareTo(nowTime) > 0) {
                redisService.del(cacheKey);
            }
            //修改了绑定的开发者时，更新缓存,若缓存为空，不必更新
            if (appRobotLoginCacheVO!= null && (operateRobotAccountUpdateDTO.getUserId() == null || !operateRobotAccountUpdateDTO.getUserId().equals(appRobotLoginCacheVO.getDeveloperUserId()))){
                AppRobotAccountInfoGetVO appRobotAccountInfoGetVO = iAppRobotLoginServiceClient.getRobotUserByAccount(appRobotLoginCacheVO.getAccount());
                appRobotLoginCacheVO.setDeveloperUserId(appRobotAccountInfoGetVO.getAppId());
                appRobotLoginCacheVO.setAppSecret(appRobotAccountInfoGetVO.getAppSecret());
                redisService.set(cacheKey,RedisConstant.REDIS_ROBOT_USER_CACHE_TIME,appRobotLoginCacheVO);
            }
            iOperateRobotAccountServiceClient.updateRobotAccount(operateRobotAccountUpdateDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】修改机器人账号信息失败",e);
        }
    }

    /**
     * <desc>
     *      删除机器人账号信息(批量)
     * </desc>
     *
     * @param ids 数据id，多个用英文逗号连接
     * @return 标准的格式化响应结果
     * @author wangzhi
     * @createDate 2018/10/12
     */
    @ResponseBody
    @PostMapping(path = "delete")
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.ROBOT_ACCOUNT_DELETE_LOG_DESC)
    public Object deleteRobotAccounts(String ids){
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ids= request.getAttribute("ids")==null?null:request.getAttribute("ids").toString();
            if (StringUtils.isBlank(ids)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iOperateRobotAccountServiceClient.deleteRobotAccounts(ids);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】删除机器人账号信息失败",e);
        }
    }

    /**
     * <desc>
     *      获取开发者账号列表
     * </desc>
     *
     * @param operateRobotAccountGetPageDTO 分页查询机器人账号信息数据DTO
     * @return 标准的格式化响应结果
     * @author wangzhi
     * @createDate 2019/09/02
     */
    @ResponseBody
    @PostMapping(path = "getDeveloperList")
    public Object getDeveloperList(OperateRobotAccountGetPageDTO operateRobotAccountGetPageDTO) {
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            operateRobotAccountGetPageDTO= HttpProtocolUtil.parseRequestParamToDTO(OperateRobotAccountGetPageDTO.class,request);
            if (operateRobotAccountGetPageDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<Map<String, Object>> data = iOperateRobotAccountServiceClient.getDeveloperList(operateRobotAccountGetPageDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【运营-机器人管理】获取开发者账号列表失败", e);
        }
    }

}
